package com.smsc.headend.connector.builder;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.OptionHelper;

import org.slf4j.LoggerFactory;
import org.slf4j.helpers.NOPLogger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;



@Component
public class LoggerBuilder {
    public static String logLevel;
    public static Boolean enableComLog;
    @Value("${logging.level.com.smsc.headend:info}")
    public void setLogLevel(String logLevel) {
        this.logLevel = logLevel;
    }

    @Value("${com.log.enable:true}")
    public void setEnableComLog(Boolean enable) {
        this.enableComLog = enable;
    }

    private static final Map<String, Logger> container = new HashMap<>();

    public static org.slf4j.Logger getLogger(String name, Class z) {
        if (!enableComLog) {
            return NOPLogger.NOP_LOGGER;
        }
        Logger logger = container.get(name);
        if(logger != null) {
            return logger;
        }
        synchronized (LoggerBuilder.class) {
            logger = container.get(name);
            if(logger != null) {
                return logger;
            }
            logger = build(name, z);
            container.put(name,logger);
        }
        return logger;
    }

    private static Logger build(String name, Class z) {
        LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
        Logger logger = context.getLogger(z + "[" + name + "]");
        logger.setAdditive(false);
        logger.setLevel(Level.valueOf(logLevel));

        RollingFileAppender appender = new RollingFileAppender();
        appender.setContext(context);
        appender.setName(name);
        appender.setFile(OptionHelper.substVars("${LOG_HOME}/com_logs/" + name + ".log",context));
        appender.setAppend(true);
        appender.setPrudent(false);

        SizeAndTimeBasedRollingPolicy policy = new  SizeAndTimeBasedRollingPolicy();
        String fp = OptionHelper.substVars("${LOG_HOME}/com_logs/%d{yyyyMMdd}/" + name + ".log.%d{yyyy-MM-dd}.%i.gz",context);
        policy.setMaxFileSize(FileSize.valueOf("128MB"));
        policy.setContext(context);
        policy.setFileNamePattern(fp);
        policy.setMaxHistory(180);
        policy.setTotalSizeCap(FileSize.valueOf("32GB"));
        policy.setParent(appender);
        policy.start();

        PatternLayoutEncoder encoder = new PatternLayoutEncoder();
        encoder.setContext(context);
        encoder.setPattern("%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread{7}] C%X{comId} M%X{meterId} ch%X{channel} %m%n");
        if ("debug".equals(logLevel)) {
            encoder.setPattern("%-5level %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{50} [%thread{7}] C%X{comId} M%X{meterId} ch%X{channel} %m%n");
        }
        encoder.start();

        appender.setRollingPolicy(policy);
        appender.setEncoder(encoder);

        appender.start();
        logger.addAppender(appender);
        return logger;
    }
}

